// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: John Zhang.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include <string>

#include "../src/pigasus-types.h"
#include "../src/cast.h"

class CastTest : public TestFixture<CastTest> {
 public:
  TEST_FIXTURE(CastTest) {
    TEST_CASE(TestCastingToInt);
    TEST_CASE(TestCastingToFloat);
    TEST_CASE(TestCastingToString);
    TEST_CASE(TestCastingFromVoid);
    TEST_CASE(TestCastingToFile);
    TEST_CASE(TestCastingToOwnType);
  }

  void TestCastingToInt() {
    int original_int = 42;
    int result = CastToInt(original_int);
    ASSERT_EQUALS(result, original_int);

    string test_str = "   42!!\n\n\t";
    result = CastToInt(test_str);
    ASSERT_EQUALS(result, original_int);
    test_str = "42";
    result = CastToInt(test_str);
    ASSERT_EQUALS(result, original_int);

    double test_float = 42.1;
    result = CastToInt(test_float);
    ASSERT_EQUALS(result, original_int);
    test_float = 42.5;
    result = CastToInt(test_float);
    ASSERT_EQUALS(result, original_int+1);
  }

  void TestCastingToFloat() {
    double original_float = 123.45;
    double result = CastToFloat(original_float);
    ASSERT_EQUALS(result, original_float);

    string test_str = "    123.45   \n";
    result = CastToFloat(test_str);
    ASSERT_EQUALS(result, original_float);
    test_str = "123.45";
    result = CastToFloat(test_str);
    ASSERT_EQUALS(result, original_float);

    int test_int = 123;
    result = CastToFloat(test_int);
    ASSERT_EQUALS(result, 123.0);
  }

  void TestCastingToString() {
    string original_string = "-12345";
    int test_int = -12345;
    string result = CastToString(test_int);
    ASSERT_EQUALS(result, original_string);

    double test_float = -12345.0;
    string expected_string = "-12345";
    result = CastToString(test_float);
    ASSERT_EQUALS(result, expected_string);

    expected_string = "bob";
    result = CastToString(expected_string);
    ASSERT_EQUALS(result, expected_string);
  }

  void TestCastingFromVoid() {
    string test_str = "bob";
    double test_float = 0.25;
    int test_int = 42;

    List list_of_string = NewList(test_str);
    Map map_of_int(test_str, test_int);
    List buffer;

    File test_file(test_str + ".txt");

    buffer.Append(test_str);
    buffer.Append(test_float);
    buffer.Append(test_int);
    buffer.Append(list_of_string);
    buffer.Append(map_of_int);
    buffer.Append(test_file);

    string result_str = CastToString(buffer[0]);
    ASSERT_EQUALS(result_str, test_str);
    double result_float = CastToFloat(buffer[1]);
    ASSERT_EQUALS(result_float, test_float);
    int result_int = CastToInt(buffer[2]);
    ASSERT_EQUALS(result_int, test_int);

    List result_list = CastToList(buffer[3]);
    result_str = CastToString(result_list[0]);
    ASSERT_EQUALS(result_str, test_str);
    Map result_map = CastToMap(buffer[4]);
    result_int = CastToInt(result_map[test_str]);
    ASSERT_EQUALS(result_int, test_int);

    File result_file = CastToFile(buffer[5]);
    ASSERT_EQUALS(test_str + ".txt", result_file.Filename());
  }

  void TestCastingToFile() {
    string test_str = "bob.txt";
    File test_file(test_str);
    ASSERT_EQUALS(test_str, test_file.Filename());
  }

  void TestCastingToOwnType() {
    string test_str = "bob";
    int test_int  = 42;
    
    List original_list = NewList(test_str);
    List result_list = CastToList(original_list);
    ASSERT_EQUALS(CastToString(original_list[0]),
                  CastToString(result_list[0]));
    result_list.Append(test_int);
    ASSERT_EQUALS(CastToInt(result_list[1]), test_int);

    Map original_map(test_str, test_int);
    Map result_map = CastToMap(original_map);
    ASSERT_EQUALS(CastToInt(original_map[test_str]),
                  CastToInt(result_map[test_str]));

    File original_file(test_str + ".txt");
    File result_file = CastToFile(original_file);
    ASSERT_EQUALS(original_file.Filename(), result_file.Filename());
  }
};

REGISTER_FIXTURE(CastTest);
